package com.ruoyi.bus.service.impl;

import com.ruoyi.bus.baidu.BaiDuApi;
import com.ruoyi.bus.constant.BookIngTypeEnum;
import com.ruoyi.bus.domain.*;
import com.ruoyi.bus.service.*;
import com.ruoyi.bus.vo.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDictTypeService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.utils.DeptUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Description
 * @Author caiyanshan
 * @Date 2021/4/15 14:45
 * @Param
 * @Return
 */
@Service
@Slf4j
public class ApiServiceImpl extends BaseService implements IApiService {
  
  private static PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
  
  @Autowired
  private ISysUserService sysUserService;
  @Autowired
  private TokenService tokenService;
  @Autowired
  private IWitAppointService appointService;
  @Autowired
  private IWitRouteService routeService;
  @Autowired
  private IWitSiteService siteService;
  @Autowired
  private IWitRouteSiteService routeSiteService;
  @Autowired
  private ISysConfigService configService;
  @Autowired
  private ISysDictTypeService dictTypeService;
  @Autowired
  private IWitCommentService commentService;
  @Autowired
  private IWitNoticeService noticeService;
  @Autowired
  private IWitPlanService planService;
  @Autowired
  private IWitBusService busService;
  @Autowired
  private RedisCache redisCache;
  @Autowired
  private IWitBannerFocusService bannerFocusService;
  @Autowired
  private IWitChangeDriverService changeDriverService;
  @Autowired
  private IWitIntoCarRecordService intoCarRecordService;
  /**
   * @Description 司机端和用户端共用逻辑
   * 1、用户信息必须存在于后台
   * 2、必须存在用户openId，否则视为未完善基本信息(注册)
   * @Author caiyanshan
   * @Date 2021/4/15 16:06
   * @Param [loginVo]
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  public AjaxResult login(LoginVo loginVo){
    SysUser user = getSysUserByPhone(loginVo.getPhone(), loginVo.getUserType());
    String phone = loginVo.getPhone();
    if (StringUtils.isNull(user)) {
      log.info("登录用户：{} 不存在.", phone);
      return AjaxResult.error("登录用户:" + phone + " 不存在,请联系单位添加.");
    } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
      log.info("登录用户：{} 已被删除.", phone);
      return AjaxResult.error("对不起，您的账号:" + phone + " 已被删除");
    } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
      log.info("登录用户：{} 已被停用.", phone);
      return AjaxResult.error("对不起，您的账号:" + phone + " 已停用");
    } else if(StringUtils.isBlank(user.getOpenId()) && loginVo.isRegister()){
      log.info("登录用户：{} 不存在用户信息", phone);
      return AjaxResult.error(100,"未注册,请注册");//未注册返回100,通知前端跳转注册
    } else if(!passwordEncoder.matches(loginVo.getPassword(), user.getPassword())){
      log.info("登录用户：{} 密码错误, 请重新输入", phone);
      return AjaxResult.error("密码错误, 请重新输入");
    }
    LoginUser loginUser = new LoginUser(user, new HashSet<String>());
    String token = tokenService.createToken(loginUser);
    loginUser.setToken(token);
    return AjaxResult.success(loginUser);
  }

  public AjaxResult openIdLogin(String openId){
    SysUser user = this.getUserByOpenId(openId);
    if(user == null){
      return AjaxResult.error("不存在该用户");
    }
    LoginUser loginUser = new LoginUser(user, new HashSet<String>());
    String token = tokenService.createToken(loginUser);
    loginUser.setToken(token);
    return AjaxResult.success(loginUser);
  }

  /**
   * 修改用户名
   * @param userName
   * @return
   */
  public AjaxResult updateUserName(String userName){
    SysUser user = new SysUser();
    user.setUserName(userName);
    user.setNickName(userName);
    user.setUserId(SecurityUtils.getLoginUser().getUser().getUserId());
    int index = sysUserService.updateUser(user);
    if(index > 0){
      return AjaxResult.success();
    }
    return AjaxResult.error("更新失败");
  }

  /**
   * 更新机构
   * @param deptId
   * @return
   */
  public AjaxResult updateUserDept(Long deptId){
    SysUser user = new SysUser();
    user.setDeptId(deptId);
    user.setUserId(SecurityUtils.getLoginUser().getUser().getUserId());
    int index = sysUserService.updateUser(user);
    if(index > 0){
      return AjaxResult.success();
    }
    return AjaxResult.error("更新失败");
  }
  
  public AjaxResult listBanner(){
    return AjaxResult.success(bannerFocusService.selectWitBannerFocusList(new WitBannerFocus()));
  }

  /**
   * 更新密码
   * @return
   */
  public AjaxResult updatePassWord(String passWord){
    SysUser user = new SysUser();
    user.setPassword(passwordEncoder.encode(passWord));
    user.setUserId(SecurityUtils.getLoginUser().getUser().getUserId());
    int index = sysUserService.updateUser(user);
    if(index > 0){
      return AjaxResult.success();
    }
    return AjaxResult.error("更新失败");
  }
  
  /**
   * @Description 司机端与用户端共用逻辑(只能注册一次)
   * 1、用户数据必须已存在于数据库，否则无法注册(先用手机号查)
   * 2、不可以存在openid，存在视为已注册，不允许重复注册
   * 3、注册只更新密码和部门及微信相关内容
   * @Author caiyanshan
   * @Date 2021/4/15 16:08
   * @Param [registerVo]
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  public AjaxResult register(RegisterVo registerVo){
    SysUser user = getSysUserByPhone(registerVo.getPhone(), registerVo.getUserType());
    String phone = registerVo.getPhone();
    if (StringUtils.isNull(user)) {
      log.info("登录用户：{} 不存在.", phone);
      return AjaxResult.error("登录用户:" + phone + " 不存在,请联系单位添加.");
    } else if(StringUtils.isNotEmpty(user.getOpenId())){
      log.info("登录用户：{} 已注册.", phone);
      return AjaxResult.error("已注册,请勿重复注册");//未注册返回100,通知前端跳转注册
    }
    SysUser tempUser = new SysUser();
    tempUser.setUserName(registerVo.getUserName());
    tempUser.setDeptId(registerVo.getDeptId());
    tempUser.setNickName(registerVo.getUserName());
    tempUser.setOpenId(registerVo.getOpenId());
    tempUser.setWxNick(registerVo.getWxNickName());
    tempUser.setWxHeadImage(registerVo.getWxHeadImage());
    tempUser.setPassword(passwordEncoder.encode(registerVo.getPassword()));
    tempUser.setUserId(user.getUserId());
    tempUser.setCreateTime(new Date());//增加注册时间
    
    int rows = sysUserService.updateUser(tempUser);
    
    return AjaxResult.success(rows);
  }
  
  private SysUser getSysUserByPhone(String phone, Integer userType){
    Map<String, Object> paramMaps = new HashMap<String, Object>();
    paramMaps.put("userType", userType);
    paramMaps.put("phone", phone);
    return sysUserService.selectUserByPhone(paramMaps);
  }

  private SysUser getUserByOpenId(String openId){
    return sysUserService.selectUserByOpenId(openId);
  }
  
  /**
   * @Description 用户预约
   * @Author caiyanshan
   * @Date 2021/4/16 9:33
   * @Param []
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  @Transactional
  public AjaxResult makeBookIng(WitAppoint witAppoint){
    List<WitRouteSite> witRouteSiteList = null;
    try{
      witRouteSiteList = this.checkBookIngData(witAppoint);
    } catch (Exception e){
      return AjaxResult.error(e.getMessage());
    }
    List<BookIngData> bookIngDataList = witAppoint.getData();
    for(BookIngData bookIngData : bookIngDataList){
      if("am".equals(bookIngData.getDriveTimes())){//早班车
        witAppoint.setStartSite(witRouteSiteList.get(0).getSiteName());
        witAppoint.setEndSite(witRouteSiteList.get(witRouteSiteList.size() -1).getSiteName());
        witAppoint.setDriveTime(bookIngData.getDriveTimes());
        witAppoint.setGotoTime(bookIngData.getGotoTime());
      } else if("pm".equals(bookIngData.getDriveTimes())){//晚班车
        witAppoint.setEndSite(witRouteSiteList.get(0).getSiteName());
        witAppoint.setStartSite(witRouteSiteList.get(witRouteSiteList.size() -1).getSiteName());
        witAppoint.setDriveTime(bookIngData.getDriveTimes());
        witAppoint.setGotoTime(bookIngData.getGotoTime());
      }else{
        throw new RuntimeException("班车班次参数错误,请检查传递的参数");
      }
      if(!this.isBookIngTime(witAppoint)){
        throw new RuntimeException("当前存在不可预约时间,请重新选择");
      }
      if(this.isBookIng(witAppoint)){
        continue;
      }
      List<WitPlan> witPlanList = this.getPlanList(witAppoint.getRouteId(), witAppoint.getDriveTime(), bookIngData.getGotoTime());
  
      if(witPlanList.size() != 0){//存在排班数据
        throw new RuntimeException("此路线存在已排班记录,请重新选择");
      }

      appointService.insertWitAppoint(witAppoint);
    }
    
    return AjaxResult.success("预约成功");
  }
  
  /**
   * @Description 临时预约借口（需把temp_status设置为1,默认是0,此状态不可更改,只做区分预约类型，无其他意义）
   * 1、检查当前时间是否可以预约
   * 3、优先给没排满车的车辆安插数据
   * 3、如果满了就使用临时预约座位
   * 3、如果都满了,那就更改状态,不可以再次预约,车满无法预约
   * @Author caiyanshan
   * @Date 2021/4/29 8:34
   * @Param []
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  @Transactional
  public AjaxResult tempMakeBooking(WitAppoint witAppoint){
    List<WitRouteSite> witRouteSiteList = null;
    try{
      witRouteSiteList = this.checkBookIngData(witAppoint);
    } catch (Exception e){
      return AjaxResult.error(e.getMessage());
    }
    BookIngData bookIngData = witAppoint.getBookIngData();//一次预约数据
    witAppoint.setTempStatus(1);//临时预约
    if("am".equals(bookIngData.getDriveTimes())){//早班车
      witAppoint.setStartSite(witRouteSiteList.get(0).getSiteName());
      witAppoint.setEndSite(witRouteSiteList.get(witRouteSiteList.size() -1).getSiteName());
      witAppoint.setDriveTime(bookIngData.getDriveTimes());
      witAppoint.setGotoTime(bookIngData.getGotoTime());
    } else if("pm".equals(bookIngData.getDriveTimes())){//晚班车
      witAppoint.setEndSite(witRouteSiteList.get(0).getSiteName());
      witAppoint.setStartSite(witRouteSiteList.get(witRouteSiteList.size() -1).getSiteName());
      witAppoint.setDriveTime(bookIngData.getDriveTimes());
      witAppoint.setGotoTime(bookIngData.getGotoTime());
    }else{
      return AjaxResult.error("班车班次参数错误,请检查传递的参数");
    }
    
    if(!this.isTempBookIngTime(witAppoint)){
      return AjaxResult.error("当前时间不可预约,请重新选择");
    }
    
    if(this.isBookIng(witAppoint)){//是否存在预约记录,存在不插入直接返回成功
      return AjaxResult.success();
    }
  
    List<WitPlan> witPlanList = this.getPlanList(witAppoint.getRouteId(), witAppoint.getDriveTime(), bookIngData.getGotoTime());
    
    if(witPlanList.size() == 0){//给与分车
      return AjaxResult.error("今日此班车还未排班,无法临时预约");
    }
    Integer seatReservation = this.getSeatReservation();
    
    WitPlan tempPlan = new WitPlan();
    //可能有多个班车
    for(WitPlan witPlan : witPlanList){//在剩下的座位中给与分配座位
      WitBus witBus = busService.selectWitBusById(witPlan.getBusId());
      if(witPlan.getAppointCount() + witPlan.getTempAppointCount() < witBus.getFullLoad() - seatReservation){
        witAppoint.setPlanId(witPlan.getPlanId());
        SysUser user = getDriverUser(witBus.getUserId());
        witAppoint.setDriverUserPhone(user.getPhonenumber());
        witAppoint.setDriverUserId(user.getUserId());
        witAppoint.setDriverUserName(user.getUserName());
        witAppoint.setBusId(witBus.getBusId());
        witAppoint.setBusNumber(witBus.getBusNumber());
        witAppoint.setBusModel(witBus.getBusModel());
        tempPlan.setPlanId(witPlan.getPlanId());
        tempPlan.setTempAppointCount(witPlan.getTempAppointCount());
        break;
      }
    }
    if(witAppoint.getPlanId() == null){//未分配排班计划,说明座位已经不够了,需要启用临时座位
      for(WitPlan witPlan : witPlanList){
        WitBus witBus = busService.selectWitBusById(witPlan.getBusId());
        if(witPlan.getAppointCount() + witPlan.getTempAppointCount() < witBus.getFullLoad()){//临时预约人数需要小于总共剩余座位数
          witAppoint.setPlanId(witPlan.getPlanId());
          SysUser user = getDriverUser(witBus.getUserId());
          witAppoint.setDriverUserPhone(user.getPhonenumber());
          witAppoint.setDriverUserId(user.getUserId());
          witAppoint.setDriverUserName(user.getUserName());
          witAppoint.setBusId(witBus.getBusId());
          witAppoint.setBusNumber(witBus.getBusNumber());
          witAppoint.setBusModel(witBus.getBusModel());
          tempPlan.setPlanId(witPlan.getPlanId());
          tempPlan.setTempAppointCount(witPlan.getTempAppointCount());
          break;
        }
      }
    }
    
    if(witAppoint.getPlanId() == null){//一个座位都没有了
      return AjaxResult.error("当前班次已经没有座位可以分配了");
    }
    
    appointService.insertWitAppoint(witAppoint);
  
    Integer count = tempPlan.getTempAppointCount();
    tempPlan.setTempAppointCount(count + 1);
    planService.updateWitPlan(tempPlan);
    return AjaxResult.success("预约成功");
  }
  
  @Override
  public AjaxResult getDictParam(String type) {
    return AjaxResult.success(dictTypeService.selectDictDataByType(type));
  }
  
  private SysUser getDriverUser(Long userId){
    SysUser sysUser = sysUserService.selectUserById(userId);
    if(sysUser != null){
      return sysUser;
    }
    return new SysUser();//可以不设置昵称,但不能报错,防止个人原因删除用户
  }
  
  /**
   * @Description 是否排过班
   * @Author caiyanshan
   * @Date 2021/4/29 14:15
   * @Param []
   * @Return boolean
   */
  private List<WitPlan> getPlanList(Long routeId, String driveTimes, Date gotoTime){
    WitPlan plan = new WitPlan();
    plan.setRouteId(routeId);
    plan.setDriveTime(driveTimes);
    plan.setSendTime(gotoTime);
    return planService.selectWitPlanList(plan);
  }
  
  /**
   * 获取座位预留数
   * @return
   */
  private int getSeatReservation(){
    String seatReservation = configService.selectConfigByKey("seat_reservation");
    try{
      return Integer.parseInt(seatReservation);
    }catch (Exception e){
      return 5;//没配置就默认给与5个预留位
    }
  }
  
  private List<WitRouteSite> checkBookIngData(WitAppoint witAppoint){
    SysUser user = SecurityUtils.getLoginUser().getUser();
    Long siteId = witAppoint.getSiteId();//站点ID
    Long routeId = witAppoint.getRouteId();//路线ID
    WitSite witSite = siteService.selectWitSiteById(siteId);
    if(witSite == null){
      throw new RuntimeException("不存在上车站点信息");
    }
    witAppoint.setSiteName(witSite.getSiteName());
    if(witAppoint.getEndSiteId() != null){
      WitSite endWitSite = siteService.selectWitSiteById(witAppoint.getEndSiteId());
      if(endWitSite == null){
        throw new RuntimeException("不存在下车站点信息");
      }
      witAppoint.setEndSiteName(endWitSite.getSiteName());
    }
    WitRoute witRoute = routeService.selectWitRouteById(routeId);
    if(witRoute == null){
      throw new RuntimeException("不存在该路线信息");
    }
    witAppoint.setRouteName(witRoute.getRouteName());
    witAppoint.setUserId(user.getUserId());
    witAppoint.setUserName(user.getUserName());
    //根据路线信息获取所有站点信息，判断早班还是晚班
    List<WitRouteSite> witRouteSiteList = routeSiteService.selectWitRouteSiteByRouteId(witRoute.getRouteId());
    if(witRouteSiteList.size() == 0){
      throw new RuntimeException("该路线下不存在站点信息，请联系管理员核实");
    }
    witRouteSiteList.sort((o1, o2) -> o1.getSort() - o2.getSort());
    return witRouteSiteList;
  }
  
  /**
   * @Description 我的预约
   * @Author caiyanshan
   * @Date 2021/4/16 15:53
   * @Param
   * @Return
   */
  public AjaxResult myBookIng(BookIngTypeEnum type){
    Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
    WitAppoint witAppoint = new WitAppoint();
    witAppoint.setUserId(userId);
    if(type == null){//查除了已预约 已取消 已完成状态外的数据
      witAppoint.setAllAppointStatus(0);
    }else{
      witAppoint.setAppointStatus(type.ordinal());//状态
    }
    startPage();
    List<WitAppoint> witAppointList = appointService.selectWitAppointList(witAppoint);
    //分类,0是已预约,1是已取消，2是已完成
    //已预约，需提供是否可以取消,
    //已完成判断是否可以点评
    if(BookIngTypeEnum.Already_BookIng == type){//已预约
      for(WitAppoint appoint : witAppointList){
        setAppointSendTime(appoint);
        if(this.isCancelBookIngTime(appoint)){//返回true可以取消
          appoint.setIsCancel(0);//0可以
        }else{
          appoint.setIsCancel(1);//1不可以
        }
      }
    }else if(BookIngTypeEnum.Finished_BookIng  == type){//已完成
      for(WitAppoint appoint : witAppointList){
        if(StringUtils.isBlank(appoint.getContent())){//评论是空则是没有评论
          appoint.setIsComment(0);//0可以点评
        }else{
          appoint.setIsComment(1);//1不可以
        }
      }
    }
    return AjaxResult.success(witAppointList);
  }
  
  /**
   * @Description 取消预约
   * 发车前X小时不允许预约
   * @Author caiyanshan
   * @Date 2021/4/16 10:19
   * @Param []
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  public AjaxResult cancelBookIng(Long appointId){
    WitAppoint witAppoint = appointService.selectWitAppointById(appointId);
    if(witAppoint == null){
      return AjaxResult.error("不存在该预约订单");
    }
    if(0 != witAppoint.getAppointStatus()){//当前状态不是可预约
      return AjaxResult.error("当前状态不可取消预约");
    }
    Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
    if(!userId.equals(witAppoint.getUserId())){//不可取消别人的订单
      return AjaxResult.error("不可取消别人的预约订单!");
    }
    if(!this.isCancelBookIngTime(witAppoint)){//发车前多少时间不允许预约
      return AjaxResult.error("当前时间已不允许取消预约");
    }
    witAppoint.setAppointStatus(1);//取消状态
    return AjaxResult.success(appointService.updateWitAppoint(witAppoint));
  }

  /**
   * 获取预约详情
   * @return
   */
  public AjaxResult getBookingDetail(Long appointId){
    return AjaxResult.success(appointService.selectWitAppointById(appointId));
  }

  /**
   * 获取点评类型
   * @return
   */
  public AjaxResult listCommentType(){
    Map<String,Object> resultMap = null;
    List<Map<String,Object>> resultList = new ArrayList<>();
    List<SysDictData> dictDataList = dictTypeService.selectDictDataByType("comment_type");
    for(SysDictData temp : dictDataList){
      resultMap = new HashMap<>();
      resultMap.put("key", temp.getDictValue());
      resultMap.put("value", temp.getDictLabel());
      resultList.add(resultMap);
    }
    return AjaxResult.success(resultList);
  }

  /**
   * 提交点评
   * @return
   */
  public AjaxResult submitComment(WitComment witComment){
    Long appointId = witComment.getAppointId();
    WitAppoint witAppoint = appointService.selectWitAppointById(appointId);
    if(witAppoint == null){
      return AjaxResult.error("不存在该预约订单");
    }
    if(witAppoint.getAppointStatus() != 2){//已完成
      return AjaxResult.error("改预约状态不可点评");
    }
    Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
    WitComment comment = new WitComment();
    comment.setAppointId(appointId);
    comment.setUserId(userId);
    List<WitComment> witCommentList = commentService.selectWitCommentList(witComment);
    if(witCommentList.size() != 0){
      return AjaxResult.error("您已经点评过了，请勿重复点评");
    }
    witComment.setUserId(userId);
    commentService.insertWitComment(witComment);
    return AjaxResult.success("点评成功");
  }

  /**
   * 首页预约数据
   * @return
   */
  public List<WitAppoint> listHomeBookIngData(){
    WitAppoint appoint = new WitAppoint();
    appoint.setUserId(SecurityUtils.getLoginUser().getUser().getUserId());
    startPage();
    List<WitAppoint> appointList = appointService.selectWitAppointList(appoint);
    for(WitAppoint temp : appointList){
      setAppointSendTime(temp);
      if(temp.getAppointStatus() == 0){
        if(this.isCancelBookIngTime(temp)){//返回true可以取消
          temp.setIsCancel(0);//0可以
        }else{
          temp.setIsCancel(1);//1不可以
        }
      }else {
        temp.setIsCancel(1);//1不可以
      }
    }
    return appointList;
  }

  /**
   * 首页通知数据
   * @return
   */
  public List<WitNotice> listHomeNoticeData(){
    WitNotice witNotice = new WitNotice();
    witNotice.setNoticeStatus(0);
    startPage();
    List<WitNotice> witNoticeList = noticeService.selectWitNoticeList(witNotice);
    return witNoticeList;
  }

  public WitNotice getNoticeByID(){
    return noticeService.selectWitNoticeById(1l);//1为通知公告
  }

  /**
   * 通知详情
   */
  public AjaxResult getNoticeDetail(Long noticeId){
    WitNotice notice = noticeService.selectWitNoticeById(noticeId);
    return AjaxResult.success(notice);
  }
  
  /**
   * @Description 排班列表
   * @Author caiyanshan
   * @Date 2021/4/22 10:28
   * @Param []
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  public AjaxResult listPlanRecord(Integer status){
    WitPlan plan = new WitPlan();
    plan.setPlanStatus(status);
    plan.setDriverUserId(SecurityUtils.getLoginUser().getUser().getUserId());
    startPage();
    List<WitPlan> witPlanList = planService.selectWitPlanList(plan);
    return AjaxResult.success(witPlanList);
  }

  /**
   * 首页展示
   * @return
   */
  public AjaxResult listHomePlanRecord(){
    return AjaxResult.success(planService.listHomePlanRecord(SecurityUtils.getLoginUser().getUser().getUserId()));
  }
  
  /**
   * @Description 排班详情
   * @Author caiyanshan
   * @Date 2021/4/22 10:28
   * @Param [planId]
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  public AjaxResult getPlanDetails(Long planId){
    WitPlan witPlan = planService.selectWitPlanById(planId);
    if(witPlan != null){
      WitRoute route = routeService.selectWitRouteById(witPlan.getRouteId());
      WitAppoint appoint = new WitAppoint();
      appoint.setPlanId(witPlan.getPlanId());
      List<WitAppoint> witAppointList = appointService.selectInCarCount(appoint);
      List<WitRouteSite> witRouteSiteList = route.getWitRouteSiteList();
      for(WitRouteSite witRouteSite : witRouteSiteList){
        for(WitAppoint witAppoint : witAppointList){
          if(witAppoint.getSiteId().longValue() == witRouteSite.getSiteId().longValue()){
            witRouteSite.setInCarCount(witAppoint.getInCarCount());
          }
        }
      }
      witPlan.setRoute(route);
    }
    return AjaxResult.success(witPlan);
  }
  
  /**
   * @Description 司机端发车,把状态置为已发车,
   * @Author caiyanshan
   * @Date 2021/4/24 13:06
   * @Param []
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  public AjaxResult sendCar(Long busId, String driveTime){
  
    WitPlan plan = new WitPlan();
    plan.setBusId(busId);
    plan.setPlanStatus(0);
    plan.setDriveTime(driveTime);
    plan.setSendTime(new Date());//只限今日
    List<WitPlan> witPlanList = planService.selectWitPlanList(plan);
    if(witPlanList.size() == 0) {//没有排班
      return AjaxResult.error("当前不可发车.");
    }
    WitPlan temp = witPlanList.get(0);
    temp.setPlanStatus(2);
    temp.setCarGoTime(new Date());
    int index = planService.updateWitPlan(temp);
    if(index > 0){
      return AjaxResult.success("发车成功.");
    }
    return AjaxResult.error("发车失败,数据未更新.");
  }
  
  /**
   * @Description 行程结束,更新排班状态为已完成,
   * 更新用户数据:
   * 1、状态为已上车的更新为已完成
   * 2、状态为已预约的更新为未完成
   * @Author caiyanshan
   * @Date 2021/4/24 13:16
   * @Param []
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  @Transactional
  public AjaxResult overCar(Long busId, String driveTime){
    WitPlan plan = new WitPlan();
    plan.setBusId(busId);
    plan.setPlanStatus(2);
    plan.setDriveTime(driveTime);
    plan.setSendTime(new Date());//只限今日
    List<WitPlan> witPlanList = planService.selectWitPlanList(plan);
    if(witPlanList.size() == 0) {//没有排班
      return AjaxResult.error("当前不存在行程中车辆,不可结束行程");
    }
    WitPlan temp = witPlanList.get(0);
    temp.setPlanStatus(1);
    temp.setCarOverTime(new Date());
    planService.updateWitPlan(temp);
  
  
    String configFlag = configService.selectConfigByKey("bus_over_driver_status_flag");
    WitAppoint witAppoint = new WitAppoint();
    witAppoint.setPlanId(temp.getPlanId());
    if(StringUtils.isBlank(configFlag) || !StringUtils.equals("0", configFlag)){//用于测试
      appointService.updateOverAppoint(witAppoint);//分两种情况,1、已完成   2、未完成
      appointService.updateNotOverAppoint(witAppoint);
    }else{
      appointService.updateTestOverAppoint(witAppoint);//更新此次班车预约和已上车的为已完成
    }
    return AjaxResult.success("行程结束");
  }
  /**
   * @Description 用户扫码上车(无法区分用户在哪里上车的，
   * 如果需要需小程序端上传扫码地点的经纬度,暂不处理)
   * 通过时间判断当前时间是上午还是下午，上午固定为am，下午固定为pm
   * 1、是否预约本次班车
   * 2、判断车辆是否发车
   * 3、上车成功,更改预约状态为6,已上车
   * @Author caiyanshan
   * @Date 2021/4/29 14:38
   * @Param []
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  @Transactional
  public AjaxResult intoCar(IntoCarVo intoCarVo){
  
    Long busId = intoCarVo.getBusId();
  
    GregorianCalendar ca = new GregorianCalendar();
    int isAm = ca.get(GregorianCalendar.AM_PM);//0是AM
    String deviceTime = "";
    if(isAm == 0){//早班
      deviceTime = "am";
    }else{
      deviceTime = "pm";
    }
    SysUser sysUser = SecurityUtils.getLoginUser().getUser();
    WitAppoint witAppoint = new WitAppoint();
    witAppoint.setDriveTime(deviceTime);
    witAppoint.setUserId(sysUser.getUserId());
    witAppoint.setGotoTime(new Date());
    //witAppoint.setAppointStatus(0);//已预约,状态在下面判断,主要针对已取消做逻辑处理
    List<WitAppoint> realAppointList = appointService.selectWitAppointList(witAppoint);//用户预约列表,应该只有一条,此次查询只用做记录,不涉及逻辑处理

    witAppoint.setBusId(busId);
    List<WitAppoint> witAppointList = appointService.selectWitAppointList(witAppoint);//用户预约列表,应该只有一条

    WitBus bus = busService.selectWitBusById(busId);

    WitIntoCarRecord record = new WitIntoCarRecord();
    record.setUserId(sysUser.getUserId());
    record.setUserName(sysUser.getUserName());
    record.setUserPhone(sysUser.getPhonenumber());
    record.setBusId(intoCarVo.getBusId());

    if(witAppointList.size() == 0){
      if(realAppointList.size() == 0){//未预约
        record.setRemark("未预约本班次班车");
        insertFailInToCar(record);
        log.info("no appoint, do not into car, the user id is : " + sysUser.getUserId() + ", the bus id is : " + busId);
        return AjaxResult.error("未预约班车", bus);
      }
      WitAppoint realAppoint = realAppointList.get(0);
      record.setRemark("预约和乘坐车辆不匹配,预约司机:" + realAppoint.getDriverUserName() +", 车牌号:" + realAppoint.getBusNumber());
      insertFailInToCar(record);
      log.info("no appoint, do not into car, the user id is : " + sysUser.getUserId() + ", the bus id is : " + busId);
      return AjaxResult.error("预约和乘坐车辆不匹配", bus);
    }
    
    WitAppoint appoint = witAppointList.get(0);
    if(appoint.getPlanId() == null){//没有排班
      record.setRemark("本次预约还未排班,请耐心等待");
      insertFailInToCar(record);
      log.info("no plan, do not into car, the user id is : " + sysUser.getUserId() + ", the bus id is : " + busId);
      return AjaxResult.error("本次预约还未排班,请耐心等待", bus);
    }
    
    WitPlan witPlan = planService.selectWitPlanById(appoint.getPlanId());
    if(witPlan.getPlanStatus() != 2){//正在行驶
      record.setRemark("该班车未发车或已行驶完成,无法上车");
      insertFailInToCar(record);
      log.info("the bus doing, do not into car, the user id is : " + sysUser.getUserId() + ", the bus id is : " + busId);
      return AjaxResult.error("该班车未发车或已行驶完成,无法上车", bus);
    }

    if(appoint.getAppointStatus() == 6){//6是已上车
      record.setRemark("您已上车,请勿重复上车.");
      insertFailInToCar(record);
      log.info("already on the bus, do not into car, the user id is : " + sysUser.getUserId() + ", the bus id is : " + busId);
      return AjaxResult.error("您已上车,请勿重复上车.", bus);
    }

    if(appoint.getAppointStatus() != 0){//6是已上车
      record.setRemark("您当前预约状态为:"+ appoint.getAppointStatusName() +",不可上车");
      insertFailInToCar(record);
      log.info("already change appoint status, do not into car, the user id is : " + sysUser.getUserId() + ", the bus id is : " + busId);
      return AjaxResult.error("您当前预约状态为:"+ appoint.getAppointStatusName() +",不可以上车", bus);
    }

    record.setBusId(witPlan.getBusId());
    record.setBusNumber(witPlan.getBusNumber());
    record.setRouteId(witPlan.getRouteId());
    record.setRouteName(witPlan.getRouteName());
    if("am".equals(witPlan.getDriveTime())){//上班
      record.setStartSiteName(appoint.getSiteName());
      record.setEndSiteName(appoint.getEndSite());
    }else{//下班
      record.setStartSiteName(appoint.getEndSite());
      record.setEndSiteName(appoint.getSiteName());
    }
    record.setPlanId(witPlan.getPlanId());
    record.setDeviceTime(witPlan.getDriveTime());
    record.setRecordStatus(0);
    record.setRemark("上车成功,祝您一路顺风");
    intoCarRecordService.insertWitIntoCarRecord(record);
  
    WitAppoint temp = new WitAppoint();
    temp.setAppointId(appoint.getAppointId());
    temp.setAppointStatus(6);//已上车
    //TODO:是否触发语音播报
    appointService.updateWitAppoint(temp);
    return AjaxResult.success("上车成功,祝您一路顺风", bus);
  }

  private void insertFailInToCar(WitIntoCarRecord record){
    record.setRecordStatus(1);
    WitBus witBus = busService.selectWitBusById(record.getBusId());
    record.setBusNumber(witBus.getBusNumber());
    intoCarRecordService.insertWitIntoCarRecord(record);
  }
  
  /**
   * @Description 我的常用路线
   * @Author caiyanshan
   * @Date 2021/4/25 8:52
   * @Param []
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  public AjaxResult myCommonRoute(){
    Long userId = SecurityUtils.getLoginUser().getUser().getUserId();
    return AjaxResult.success(routeService.myCommonRoute(userId));
  }
  
  /**
   * @Description 获取系统内统计数据(司机,班车,路线总数)
   * @Author caiyanshan
   * @Date 2021/4/26 10:31
   * @Param []
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  public AjaxResult getDataCount(){
    String key = "dataCount";
    Map<String, Object> data = redisCache.getCacheObject(key);
    if(data == null){
      data = new HashMap<String, Object>();
      Integer userCount = sysUserService.selectCountDiverUser();//司机数量
      Integer busCount = busService.selectCountBus();//车数量
      Integer routeCount = routeService.selectCountRoute();//路线数量
      data.put("userCount", userCount);
      data.put("busCount", busCount);
      data.put("routeCount", routeCount);
      redisCache.setCacheObject(key, data, 1, TimeUnit.MINUTES);//数据缓存1分钟
    }
    return AjaxResult.success(data);
  }
  
  /**
   * @Description 获取系统内参数
   * @Author caiyanshan
   * @Date 2021/4/27 10:18
   * @Param [key]
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  public AjaxResult getSysParam(String key){
    Map<String, Object> paramMap = new HashMap<String, Object>();
    paramMap.put("value", configService.selectConfigByKey(key));
    return AjaxResult.success(paramMap);
  }
  
  /**
   * @Description 朗读站点信息
   * @Author caiyanshan
   * @Date 2021/4/27 10:17
   * @Param []
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  public AjaxResult reportSite(Long routeId, Long siteId, String deviceTime){
    
    Map<String, Object> resultMap = new HashMap<String, Object>();
    WitRoute route = routeService.selectWitRouteByIdNoCache(routeId);
    List<WitRouteSite> witRouteSiteList = route.getWitRouteSiteList();
    
    if("am".equals(deviceTime)){//早班
      witRouteSiteList.sort((o1, o2) -> o1.getSort() - o2.getSort());
    }
    if("pm".equals(deviceTime)){//晚班
      witRouteSiteList.sort((o1, o2) -> o2.getSort() - o1.getSort());
    }
    for(int i = 0; i < witRouteSiteList.size(); i++){
      WitRouteSite witRouteSite = witRouteSiteList.get(i);
      if(witRouteSite.getSiteId().longValue() == siteId.longValue()){
        if(i == witRouteSiteList.size() - 1){//最后一个站点,
          this.createSiteVoice(witRouteSite, deviceTime, null);
          resultMap.put("thisOne", witRouteSite.getThisOne());
          break;
        }
        this.createSiteVoice(witRouteSite, deviceTime, witRouteSiteList.get(i+1).getSiteName());
        resultMap.put("thisOne", witRouteSite.getThisOne());
        if("am".equals(deviceTime)){//早班
          resultMap.put("nextOne", witRouteSite.getNextAm());
        }
        if("pm".equals(deviceTime)){//晚班
          resultMap.put("nextOne", witRouteSite.getNextPm());
        }
      }
    }
    
    return AjaxResult.success(resultMap);
  }
  
  /**
   * @Description 上报站点数据
   * @Author caiyanshan
   * @Date 2021/7/5 9:39
   * @Param []
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  @Transactional
  @Log(title = "站点数据上报", businessType = BusinessType.UPDATE)
  public AjaxResult reportSiteInfo(SiteInfo siteInfo){
    
    WitSite site = new WitSite();
    site.setSiteId(siteInfo.getSiteId());
    site.setLatitude(siteInfo.getLatitude());
    site.setLongitude(siteInfo.getLongitude());
    site.setSiteName(siteInfo.getSiteName());
    siteService.updateWitSite(site);
    
    if(siteInfo.getRouteId() != null){
      WitRouteSite witRouteSite = new WitRouteSite();
      witRouteSite.setAmArriveTime(siteInfo.getAmArriveTime());
      witRouteSite.setPmArriveTime(siteInfo.getPmArriveTime());
      witRouteSite.setRouteId(siteInfo.getRouteId());
      witRouteSite.setSiteId(siteInfo.getSiteId());
      routeSiteService.updateWitRouteSiteByRouteId(witRouteSite);
    }
    
    return AjaxResult.success();
  }
  
  public AjaxResult myRoute(){
    SysUser user = SecurityUtils.getLoginUser().getUser();
    return AjaxResult.success(routeService.myRoute(user.getUserId()));
  }
  
  public AjaxResult todayPlanBus(){
    String dept = DeptUtils.getInstitutionIdsBySysUser(SecurityUtils.getLoginUser().getUser());
    startPage();
    List<WitPlan> planList = planService.todayPlan(dept);
    return AjaxResult.success(planList);
  }
  
  public AjaxResult noPlanDriverUser(){
    String dept = DeptUtils.getInstitutionIdsBySysUser(SecurityUtils.getLoginUser().getUser());
    return AjaxResult.success(sysUserService.noPlanDriverUser(dept));
  }
  
  /**
   * @Description 调度端更改排班中的司机
   * @Author caiyanshan
   * @Date 2021/7/27 15:24
   * @Param [changeDriver]
   * @Return com.ruoyi.common.core.domain.AjaxResult
   */
  @Transactional
  public AjaxResult changeDriver(ChangeDriver changeDriver){
    
    WitPlan witPlan = planService.selectWitPlanById(changeDriver.getPlanId());
    if(witPlan == null){
      return AjaxResult.error("不存在该排班计划");
    }
    
    if(witPlan.getPlanStatus() != 0){
      return AjaxResult.error("当前排班状态不可更改司机");
    }
    
    SysUser sysUser = sysUserService.selectUserById(changeDriver.getUserId());
    if(sysUser == null){
      return AjaxResult.error("新司机不存在");
    }

    WitChangeDriver witChangeDriver = new WitChangeDriver();
    witChangeDriver.setOldUserId(witPlan.getDriverUserId());
    witChangeDriver.setOldUserName(witPlan.getDriverUserName());
    witChangeDriver.setChangeBus(0);
    String value = configService.selectConfigByKey("change_driver_and_bus");//是否换车
    if(!"0".equals(value)){//默认为0,0为不更改，1为更改(更改需要更换预约数据表里面的车辆信息)
      WitBus witBus = new WitBus();
      witBus.setUserId(sysUser.getUserId());
      witBus.setBusStatus(0);
      List<WitBus> witBusList = busService.selectWitBusList(witBus);
      if(witBusList.size() == 0){
        return AjaxResult.error("该用户下不存在车辆");
      }
      witBus = witBusList.get(0);
      witPlan.setBusId(witBus.getBusId());
      witPlan.setBusModel(witBus.getBusModel());
      witPlan.setBusNumber(witBus.getBusNumber());
      witChangeDriver.setChangeBus(1);
    }

    witPlan.setDriverUserId(sysUser.getUserId());
    witPlan.setDriverUserName(sysUser.getUserName());
    planService.updateWitPlan(witPlan);
    
    witChangeDriver.setRouteId(witPlan.getRouteId());
    witChangeDriver.setRouteName(witPlan.getRouteName());
    witChangeDriver.setRemark(changeDriver.getRemark());
    witChangeDriver.setNewUserId(sysUser.getUserId());
    witChangeDriver.setNewUserName(sysUser.getUserName());

    SysUser user = SecurityUtils.getLoginUser().getUser();
    witChangeDriver.setUserId(user.getUserId());
    witChangeDriver.setUserName(user.getUserName());

    WitAppoint witAppoint = new WitAppoint();
    witAppoint.setDriverUserId(sysUser.getUserId());
    witAppoint.setDriverUserName(sysUser.getUserName());
    witAppoint.setDriverUserPhone(sysUser.getPhonenumber());
    witAppoint.setPlanId(witPlan.getPlanId());

    if(witChangeDriver.getChangeBus() == 1){//给与预约数据更改
      witAppoint.setBusModel(witPlan.getBusModel());
      witAppoint.setBusId(witPlan.getBusId());
      witAppoint.setBusNumber(witPlan.getBusNumber());
    }

    appointService.updateWitAppointByPlanId(witAppoint);
  
    changeDriverService.insertWitChangeDriver(witChangeDriver);
    return AjaxResult.success();
  }

  public AjaxResult changeDriverPlan(ChangeDriverPlan changeDriverPlan){


    String startTime = "";
    if("am".equals(changeDriverPlan.getDriveTimes())){
      startTime = configService.selectConfigByKey("AmStartTime");
    } else {
      startTime = configService.selectConfigByKey("PmStartTime");
    }

    Date nowTime = DateUtils.getNowDate();//当前时间
    Date changeTime = DateUtils.splicingTime(changeDriverPlan.getGotoTime(), startTime);//预约排班时间
    //当前时间应该小于排班时间
    if(nowTime.getTime() > changeTime.getTime()){
      return AjaxResult.error("当前时间已不允许换班");
    }

    SysUser sysUser = SecurityUtils.getLoginUser().getUser();
    WitChangeDriver witChangeDriver = new WitChangeDriver();
    witChangeDriver.setDriveTime(changeDriverPlan.getDriveTimes());
    witChangeDriver.setGotoTime(changeDriverPlan.getGotoTime());
    witChangeDriver.setNewUserId(changeDriverPlan.getUserId());
    List<WitChangeDriver> witChangeDriverList = changeDriverService.selectWitChangeDriverList(witChangeDriver);
    if(witChangeDriverList.size() != 0){
      return AjaxResult.error("该用户在该班次已被预约换过班,请勿换班");
    }
    witChangeDriver.setNewUserId(null);
    witChangeDriver.setOldUserId(sysUser.getUserId());
    List<WitChangeDriver> rel = changeDriverService.selectWitChangeDriverList(witChangeDriver);
    if(rel.size() != 0){
      return AjaxResult.error("您已在该班次预约过换班,请勿换班");
    }

    witChangeDriver.setChangeBus(changeDriverPlan.getChangeStatus());
    witChangeDriver.setNewUserId(changeDriverPlan.getUserId());
    SysUser newUser = sysUserService.selectUserById(changeDriverPlan.getUserId());
    witChangeDriver.setNewUserName(newUser.getUserName());
    witChangeDriver.setOldUserName(sysUser.getUserName());
    WitBus bus = new WitBus();
    bus.setUserId(sysUser.getUserId());
    bus.setBusStatus(0);
    List<WitBus> busList = busService.selectWitBusList(bus);
    if(busList.size() == 0){
      return AjaxResult.error("您名下没车,不可换绑");
    }

    if(changeDriverPlan.getChangeStatus().intValue() == 1){//换车
      WitBus busTemp = new WitBus();
      busTemp.setUserId(changeDriverPlan.getUserId());
      busTemp.setBusStatus(0);
      List<WitBus> buses = busService.selectWitBusList(busTemp);
      if(buses.size() == 0){
        return AjaxResult.error("司机名下没有绑定车辆,不可换绑车辆");
      }
    }
    bus = busList.get(0);
    witChangeDriver.setRouteId(bus.getRouteId());
    witChangeDriver.setRouteName(bus.getRouteName());
    changeDriverService.insertWitChangeDriver(witChangeDriver);
    return AjaxResult.success();
  }
  
  public AjaxResult listChangeRecord(){
    WitChangeDriver witChangeDriver = new WitChangeDriver();
    witChangeDriver.setUserId(SecurityUtils.getLoginUser().getUser().getUserId());
    startPage();
    List<WitChangeDriver> witChangeDriverList = changeDriverService.selectWitChangeDriverList(witChangeDriver);
    return AjaxResult.success(witChangeDriverList);
  }

  public AjaxResult listChangeDriver(){
    return AjaxResult.success(sysUserService.listDriverChangeUser());
  }
  
  private void createSiteVoice(WitRouteSite routeSite, String deviceTime, String nextSiteName){
    if(StringUtils.isBlank(routeSite.getThisOne())){//本站没数据
      String url = BaiDuApi.uploadSiteVoice("本站是" + routeSite.getSiteName());
      WitSite witSite = this.getWitSite(routeSite.getSiteId());
      witSite.setThisOne(url);
      siteService.updateWitSite(witSite);
      routeSite.setThisOne(url);
    }
    if(StringUtils.isBlank(nextSiteName)){
      return;
    }
    if("am".equals(deviceTime)){//早班
      if(StringUtils.isBlank(routeSite.getNextAm())){//下一站早班没数据
        String url = BaiDuApi.uploadSiteVoice("前方到站" + nextSiteName);
        WitSite witSite = this.getWitSite(routeSite.getSiteId());
        witSite.setNextAm(url);
        siteService.updateWitSite(witSite);
        routeSite.setNextAm(url);
      }
    }
    if("pm".equals(deviceTime)){//晚班
      if(StringUtils.isBlank(routeSite.getNextPm())){//下一站晚班没数据
        String url = BaiDuApi.uploadSiteVoice("前方到站" + nextSiteName);
        WitSite witSite = this.getWitSite(routeSite.getSiteId());
        witSite.setNextPm(url);
        siteService.updateWitSite(witSite);
        routeSite.setNextPm(url);
      }
    }
  }
  private WitSite getWitSite(Long siteId){
    WitSite witSite = new WitSite();
    witSite.setSiteId(siteId);
    return witSite;
  }
  
  /**
   * @Description 设置发车时间（预约时间加上设置的发车时间）
   * @Author caiyanshan
   * @Date 2021/4/16 16:36
   * @Param []
   * @Return void
   */
  private void setAppointSendTime(WitAppoint appoint){
    appoint.setSendTime(this.getAppointSendTime(appoint));
  }

  private Date getAppointSendTime(WitAppoint appoint){
    WitRoute route = routeService.selectWitRouteById(appoint.getRouteId());
    Date sendTime = null;
    if("am".equals(appoint.getDriveTime())){
      sendTime = DateUtils.splicingTime(appoint.getGotoTime(), route.getStartAmTime());
    }else if("pm".equals(appoint.getDriveTime())){
      sendTime = DateUtils.splicingTime(appoint.getGotoTime(), route.getStartPmTime());
    }
    return sendTime;
  }
  
  /**
   * @Description 按照userID 时间 班次 状态 查询是否已经预约了，做幂等次校验
   * TODO:暂不做幂等次校验,如果存在预约,则不处理，不存在的插入记录
   * @Author caiyanshan
   * @Date 2021/4/16 13:45
   * @Param [temp]
   * @Return boolean
   */
  private boolean isBookIng(WitAppoint temp){
    WitAppoint witAppoint = new WitAppoint();
    witAppoint.setAppointStatus(0);//已预约
    witAppoint.setDriveTime(temp.getDriveTime());
    witAppoint.setGotoTime(temp.getGotoTime());
    witAppoint.setUserId(temp.getUserId());
    List<WitAppoint> witAppointList = appointService.selectWitAppointList(witAppoint);
    if(witAppointList.size() > 0){//存在
      return true;
    }
    return false;
  }
  
  /**
   * @Description 车辆临时预约接口校验时间
   * @Author caiyanshan
   * @Date 2021/4/29 9:08
   * @Param [witAppoint]
   * @Return boolean
   */
  private boolean isTempBookIngTime(WitAppoint witAppoint){
    Date date = DateUtils.getNowDate();
    WitRoute route = routeService.selectWitRouteById(witAppoint.getRouteId());
    Date sendTime = null;
    Date bokIngTime = null;
    if("am".equals(witAppoint.getDriveTime())){
      String amStartTime = configService.selectConfigByKey("AmStartTime");//获取提前预约时间
      sendTime = DateUtils.splicingTime(witAppoint.getGotoTime(), route.getStartAmTime());
      bokIngTime = DateUtils.splicingTime(date, amStartTime);
    }else if("pm".equals(witAppoint.getDriveTime())){
      String pmStartTime = configService.selectConfigByKey("PmStartTime");//获取提前预约时间
      sendTime = DateUtils.splicingTime(witAppoint.getGotoTime(), route.getStartPmTime());
      bokIngTime = DateUtils.splicingTime(date, pmStartTime);
    }
    long sendLong = sendTime.getTime();
    long nowLong = date.getTime();
    long tempLong = bokIngTime.getTime();
    //现在时间要大于发车时间,小于临时预约时间
    if(nowLong > tempLong && nowLong < sendLong){
      return true;
    }
    return false;
  }
  
  /**
   * @Description 当前时间一定小于发车时间X小时(否则不允许预约)
   * @Author caiyanshan
   * @Date 2021/4/16 14:10
   * @Param [bookingTime]
   * @Return boolean
   */
  private boolean isBookIngTime(WitAppoint witAppoint){
    String bookingAdvanceTime = configService.selectConfigByKey("booking_advance_time");//获取提前预约时间
    Integer time ;//小时
    try{
      time = Integer.parseInt(bookingAdvanceTime);
    }catch (Exception e){
      time = 3;//转换失败时默认值为5
    }
    //先组合时间,求出预约发车时间,然后和当前时间进行比对
    Date date = this.getAppointSendTime(witAppoint);

    Date now = DateUtils.getNowDate();
    long dateLong = date.getTime();
    long nowLong = now.getTime();
    long diff = dateLong - nowLong;
    if(diff > time*60*60*1000 && diff < 7*24*60*60*1000){//7天内
      return true;
    }
    return false;
  }
  
  /**
   * @Description 取消预约是否在规定时间范围内
   * @Author caiyanshan
   * @Date 2021/4/16 15:20
   * @Param [bookingTime, route, driveTimes]
   * @Return boolean
   */
  private boolean isCancelBookIngTime(WitAppoint witAppoint){
    String bookingCancelTime = configService.selectConfigByKey("booking_cancel_time");//获取提前预约时间
    Integer time ;//小时
    try{
      time = Integer.parseInt(bookingCancelTime);
    }catch (Exception e){
      time = 1;//转换失败时默认值为1
    }
    //先组合时间,求出预约发车时间,然后和当前时间进行比对
    Date date = this.getAppointSendTime(witAppoint);
    Date now = DateUtils.getNowDate();
    long dateLong = date.getTime();
    long nowLong = now.getTime();
    long diff = dateLong - nowLong;
    if(diff > time*60*60*1000){//发车时间大于配置时间（换算成毫秒）
      return true;
    }
    return false;
  }

}
